/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.workbench;

import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.entities.beans.table.TableField;
import cn.easyplatform.entities.beans.table.TableFk;
import cn.easyplatform.entities.beans.table.TableIndex;
import cn.easyplatform.lang.Lang;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.biz.*;
import cn.easyplatform.studio.cmd.biz.PagingCmd;
import cn.easyplatform.studio.cmd.biz.QueryCmd;
import cn.easyplatform.studio.cmd.entity.*;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.ExportExcel;
import cn.easyplatform.studio.utils.ImportExecl;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.*;
import cn.easyplatform.studio.web.editors.AbstractPanelEditor;
import cn.easyplatform.studio.web.editors.Editor;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.type.FieldType;
import cn.easyplatform.type.ModeType;
import cn.easyplatform.web.ext.cmez.CMeditor;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.zkoss.poi.hssf.usermodel.HSSFWorkbook;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zul.*;
import org.zkoss.zul.event.PagingEvent;
import org.zkoss.zul.event.ZulEvents;
import org.zkoss.zul.impl.InputElement;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class DbViewEditor extends AbstractPanelEditor {

    private Tabbox container;

    private Listbox tables;

    private Toolbarbutton runBtn;

    private Toolbarbutton insertBtn;

    private Toolbarbutton deleteBtn;

    private Toolbarbutton saveBtn;

    private Toolbarbutton undoBtn;

    private Toolbarbutton dataImport;

    private Toolbarbutton dataExport;

    private Toolbarbutton tempExport;

    private Map<EntityVo, List<EntityVo>> data;

    private LoginUserVo loginUserVo;

    /**
     * @param workbench
     * @param id
     */
    public DbViewEditor(WorkbenchController workbench, String id) {
        super(workbench, id);
        this.loginUserVo = Contexts.getUser();
    }

    @Override
    public void create(Object... args) {
        Idspace is = createPanel(Labels.getLabel("menu.db.view"), "~./images/db.gif", "~./include/editor/workbench/dbview.zul");
        for (Component comp : is.getFellows()) {
            if (comp instanceof Toolbarbutton) {
                comp.addEventListener(Events.ON_CLICK, this);
                if (comp.getId().equals("dbview_toolbarbutton_run"))
                    runBtn = (Toolbarbutton) comp;
                else if (comp.getId().equals("dbview_toolbarbutton_insert"))
                    insertBtn = (Toolbarbutton) comp;
                else if (comp.getId().equals("dbview_toolbarbutton_delete"))
                    deleteBtn = (Toolbarbutton) comp;
                else if (comp.getId().equals("dbview_toolbarbutton_save"))
                    saveBtn = (Toolbarbutton) comp;
                else if (comp.getId().equals("dbview_toolbarbutton_undo"))
                    undoBtn = (Toolbarbutton) comp;
                else if (comp.getId().equals("dbview_toolbarbutton_dataExport") && loginUserVo.isAuthorized("dataExport")) {
                    dataExport = (Toolbarbutton) comp;
                    if (Contexts.getProject().getMode() == ModeType.DEVELOP) {
                        dataExport.setDisabled(false);
                    }
                } else if (comp.getId().equals("dbview_toolbarbutton_tempExport")) {
                    tempExport = (Toolbarbutton) comp;
                    tempExport.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
                        @Override
                        public void onEvent(Event event) throws Exception {
                            Filedownload.save("~./excel/datas_temp.xls", null);
                        }
                    });
                    if (Contexts.getProject().getMode() == ModeType.DEVELOP) {
                        tempExport.setDisabled(false);
                    }
                } else if (comp.getId().equals("dbview_toolbarbutton_dataImport") && loginUserVo.isAuthorized("dataImport")) {
                    dataImport = (Toolbarbutton) comp;
                    dataImport.addEventListener(Events.ON_UPLOAD, this);
                    if (Contexts.getProject().getMode() == ModeType.DEVELOP) {
                        dataImport.setDisabled(false);
                    }
                } else {
                    String AuthorizedKey = null;
                    if (comp.getId().equals("dbview_toolbarbutton_createSql"))
                        AuthorizedKey = "createSql";
                    boolean isAuthorized = loginUserVo.isAuthorized(AuthorizedKey);
                    ((Button) comp).setDisabled(!isAuthorized);
                }
            } else if (comp.getId().equals("dbview_listbox_tables")) {
                tables = (Listbox) comp;
            } else if (comp.getId().equals("dbview_tabbox_container")) {
                container = (Tabbox) comp;
                container.addEventListener(Events.ON_SELECT, this);
            } else if (comp.getId().equals("dbview_bandbox_search")) {
                comp.addEventListener(Events.ON_OK, this);
            }
        }
        data = new HashMap<EntityVo, List<EntityVo>>();
        redrawList();
    }

    private void redrawList() {
        List<EntityVo> ds = StudioApp.execute(new QueryModelCmd(
                EntityType.DATASOURCE.getName()));
        ProjectBean pb = Contexts.getProject();
        EntityVo master = null;
        for (EntityVo vo : ds) {
            if (pb.getBizDb().equals(vo.getId())) {
                master = vo;
                break;
            }
        }
        ds.remove(master);
        Listgroup group = createDb(master);
        List<EntityVo> result = StudioApp.execute(new QueryTableCmd(master
                .getId()));
        createTables(group, result);
        data.put(master, result);

        for (EntityVo vo : ds) {
            group = createDb(vo);
            group.setOpen(false);
            group.addEventListener(Events.ON_OPEN, this);
        }
    }

    private Listgroup createDb(EntityVo ds) {
        Listgroup group = new Listgroup();
        group.appendChild(new Listcell(ds.getId()));
        group.appendChild(new Listcell(ds.getName()));
        group.setValue(ds);
        tables.appendChild(group);
        return group;
    }

    private void createTables(Listgroup group, List<EntityVo> data) {
        List<Listitem> items = tables.getItems();
        int pos = items.indexOf(group);
        for (int i = 0; i < data.size(); i++) {
            EntityVo tv = data.get(i);
            Listitem ti = new Listitem();
            ti.appendChild(new Listcell(tv.getId()));
            ti.appendChild(new Listcell(tv.getName()));
            ti.setDraggable("table");
            ti.setValue(tv);
            ti.addEventListener(Events.ON_DOUBLE_CLICK, this);
            items.add(pos + i + 1, ti);
        }
    }

    @Override
    public void dispatch(Event event) {
        Component c = event.getTarget();
        if (c instanceof Listgroup) {
            OpenEvent evt = (OpenEvent) event;
            if (evt.isOpen() && evt.getTarget().getAttribute("loaded") == null) {
                Listgroup group = (Listgroup) c;
                EntityVo ds = group.getValue();
                List<EntityVo> result = StudioApp.execute(new QueryTableCmd(ds
                        .getId()));
                createTables((Listgroup) c, result);
                data.put(ds, result);
                evt.getTarget().setAttribute("loaded", "1");
            }
        } else if (c instanceof Toolbarbutton) {
            if (c.getId().equals("dbview_toolbarbutton_createSql"))
                createQueryTab();
            else if (c == runBtn) {
                QueryPanel panel = container.getSelectedTab().getValue();
                panel.run();
            } else if (c == deleteBtn) {
                EditorPanel editor = container.getSelectedTab().getValue();
                deleteTable(editor);
            } else if (c == undoBtn) {
                EditorPanel editor = container.getSelectedTab().getValue();
                editor.onRefresh();
            } else if (c == insertBtn) {
                EditorPanel editor = container.getSelectedTab().getValue();
                editor.onCreate();
            } else if (c == saveBtn) {
                EditorPanel editor = container.getSelectedTab().getValue();
                editor.onSave();
            } else if (c == dataImport) {
                if (event.getName().equals(Events.ON_UPLOAD)) {
                    UploadEvent evt = (UploadEvent) event;
                    org.zkoss.util.media.Media media = evt.getMedia();
                    if ("application/vnd.ms-excel".equals(media.getContentType()) ||
                            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(media.getContentType())) {
                        try {
                            Map<String, Object> map = null;
                            if ("application/vnd.ms-excel".equals(media.getContentType())) {
                                map = new ImportExecl().read(new ByteArrayInputStream(media.getByteData()), true, ImportExecl.DATA);
                            } else {
                                map = new ImportExecl().read(new ByteArrayInputStream(media.getByteData()), false, ImportExecl.DATA);
                            }
                            AbstractView.createExcelImportView(
                                    new EditorCallback<List<Object>>() {

                                        @Override
                                        public List<Object> getValue() {
                                            return null;
                                        }

                                        @Override
                                        public void setValue(List<Object> dataList) {
                                            for (Object object : dataList) {
                                                Map<String, Object> m = (Map<String, Object>) object;
                                                List<Map<TableField, String>> data = (List<Map<TableField, String>>) m.get("data");
                                                TableBean tableBean = (TableBean) m.get("tableBean");
                                                if (data.size() != 0) {
                                                    List<FieldVo> fieldVos = new ArrayList<FieldVo>();
                                                    for (Map<TableField, String> rowData : data) {
                                                        fieldVos.clear();
                                                        String columns = "";
                                                        String placeholders = "";
                                                        StringBuilder sb = new StringBuilder();
                                                        Set<TableField> tableFields = rowData.keySet();
                                                        for (TableField tableField : tableFields) {
                                                            Object value = rowData.get(tableField);
                                                            switch (tableField.getType()) {
                                                                case TIME:
                                                                case DATE:
                                                                case DATETIME:
                                                                    try {
                                                                        value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(rowData.get(tableField) + "");
                                                                    } catch (ParseException e) {
                                                                        try {
                                                                            value = new SimpleDateFormat("yyyy-MM-dd").parse(rowData.get(tableField) + "");
                                                                        } catch (ParseException e1) {
                                                                            try {
                                                                                value = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse(rowData.get(tableField) + "");
                                                                            } catch (ParseException e2) {
                                                                                try {
                                                                                    value = new SimpleDateFormat("dd/MM/yyyy").parse(rowData.get(tableField) + "");
                                                                                } catch (ParseException e3) {
                                                                                    e3.printStackTrace();
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                    break;
                                                                default:
                                                                    break;
                                                            }
                                                            fieldVos.add(new FieldVo(tableField.getType(), value));
                                                            columns += tableField.getName() + ",";
                                                            placeholders += "?,";
                                                        }
                                                        sb.append("INSERT INTO ").append(tableBean.getId()).append("(")
                                                                .append(columns.substring(0, columns.length() - 1)).append(") VALUES(")
                                                                .append(placeholders.substring(0, placeholders.length() - 1)).append(")");
                                                        try {
                                                            StudioApp.execute(new UpdateCmd(tableBean.getSubType(), sb.toString(), fieldVos));
                                                        } catch (Exception e) {
                                                            continue;
                                                        }
                                                    }
                                                }
                                            }
                                            WebUtils.showSuccess(Labels.getLabel("editor.db.insert"));
                                            tables.getItems().clear();
                                            redrawList();
                                        }

                                        @Override
                                        public String getTitle() {
                                            return Labels.getLabel("editor.table.build.excel.import");
                                        }

                                        @Override
                                        public Page getPage() {
                                            return dataExport.getPage();
                                        }

                                        @Override
                                        public Editor getEditor() {
                                            return null;
                                        }
                                    }
                                    , map, "DB", event.getTarget()).doOverlapped();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else if (media != null) {
                        Messagebox.show("Not an excel: " + media, "Error", Messagebox.OK, Messagebox.ERROR);
                    }
                }
            } else if (c == dataExport) {
                AbstractView.createDbMultipleView(
                        new EditorCallback<List<EntityVo>>() {

                            @Override
                            public List<EntityVo> getValue() {
                                return null;
                            }

                            @Override
                            public void setValue(List<EntityVo> value) {
                                List<TableBean> tableBeans = new ArrayList<>();
                                List<List<Object[]>> datas = new ArrayList<>();
                                for (EntityVo evo : value) {
                                    TableBean tb = (TableBean) StudioApp.execute(new GetEntityCmd(evo.getId()));
                                    String sql;
                                    String orderBy;
                                    Map<String, FieldVo> filterParams = new HashMap<String, FieldVo>();
                                    StringBuilder sb = new StringBuilder("SELECT ");
                                    Iterator<TableField> it = tb.getFields().iterator();
                                    while (it.hasNext()) {
                                        TableField tf = it.next();
                                        sb.append(tf.getName());
                                        if (it.hasNext())
                                            sb.append(",");
                                    }
                                    sb.append(" FROM ").append(tb.getId());
                                    sql = sb.toString();
                                    if (tb.getKey() != null && !tb.getKey().isEmpty())
                                        orderBy = tb.getKey().get(0);
                                    else
                                        orderBy = tb.getFields().get(0).getName();
                                    BizQueryVo vo = new BizQueryVo();
                                    vo.setId(tb.getSubType());
                                    if (filterParams.isEmpty())
                                        vo.setSql(sql);
                                    else {
                                        sb.append(" WHERE ");
                                        Iterator<Map.Entry<String, FieldVo>> itr = filterParams
                                                .entrySet().iterator();
                                        while (itr.hasNext()) {
                                            Map.Entry<String, FieldVo> entry = itr.next();
                                            sb.append(entry.getKey()).append(" ")
                                                    .append(entry.getValue().getName()).append("?");
                                            if (itr.hasNext())
                                                sb.append(" AND ");
                                        }
                                        vo.setSql(sb.toString());
                                        vo.setParams(Lang.collection2array(filterParams.values()));
                                    }
                                    vo.setOrderBy(orderBy);
                                    ResultVo result = StudioApp.execute(new QueryAllCmd(vo));
                                    tableBeans.add(tb);
                                    datas.add(result.getData());
                                }
                                HSSFWorkbook wb = new HSSFWorkbook();
                                for (int r = 0; r < tableBeans.size(); r++) {
                                    TableBean tableBean = tableBeans.get(r);

                                    String[] sheetOneTitle = new String[tableBean.getFields().size()];
                                    for (int i = 0; i < tableBean.getFields().size(); i++) {
                                        sheetOneTitle[i] = tableBean.getFields().get(i).getName();
                                    }
                                    List<Object[]> data = datas.get(r);
                                    String sheetOnecontent[][] = null;
                                    if (data != null && data.size() != 0) {
                                        sheetOnecontent = new String[data.size()][data.get(0).length];
                                        for (int i = 0; i < data.size(); i++) {
                                            Object[] objects = data.get(i);
                                            for (int a = 0; a < objects.length; a++) {
                                                sheetOnecontent[i][a] = objects[a] != null ? objects[a] + "" : "";
                                            }
                                        }
                                    }
                                    List<Map<String, Object>> excelData = new ArrayList<>();
                                    Map<String, Object> three = new HashMap<String, Object>();
                                    three.put("title", sheetOneTitle);
                                    three.put("values", sheetOnecontent);
                                    excelData.add(three);
                                    ExportExcel.getHSSFWorkbook(tableBean.getId(), excelData, wb);
                                }
                                try {
                                    File tempFile = File.createTempFile("datas", ".xls");
                                    FileOutputStream os = new FileOutputStream(tempFile);
                                    wb.write(os);
                                    os.flush();
                                    os.close();
                                    Filedownload.save(tempFile, "application/vnd.ms-excel");
                                    tempFile.deleteOnExit();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }

                            @Override
                            public String getTitle() {
                                return Labels.getLabel("editor.table.build.excel.export");
                            }

                            @Override
                            public Page getPage() {
                                return dataExport.getPage();
                            }

                            @Override
                            public Editor getEditor() {
                                return null;
                            }
                        }, event.getTarget()
                ).doOverlapped();
            }
        } else if (c instanceof Tab) {
            if (event.getName().equals(Events.ON_CLOSE)) {
                if (container.getTabs().getChildren().size() == 1) // 没有Tab了
                    setToolbarState(100);
                else {
                    Object editor = container.getSelectedTab().getValue();
                    if (editor instanceof QueryPanel) {
                        setToolbarState(3);
                    } else {
                        setToolbarState(((EditorPanel) editor).state);
                    }
                }
            } else if (container.getSelectedIndex() >= 0) {
                Object editor = container.getSelectedTab().getValue();
                if (editor instanceof QueryPanel) {
                    setToolbarState(3);
                } else {
                    setToolbarState(((EditorPanel) editor).state);
                }
            }
        } else if (c instanceof Listitem) {
            EntityVo tb = ((Listitem) c).getValue();
            if (StudioApp.execute(new CheckTableCmd(tb.getId())))
                createEditorTab(tb);
            else
                WebUtils.showInfo(Labels.getLabel("app.db.not.found"));
        } else if (c.getId().equals("dbview_bandbox_search")) {
            Textbox search = (Textbox) c;
            /*String val = null;
            if (event instanceof OpenEvent) {
                OpenEvent evt = (OpenEvent) event;
                val = (String) evt.getValue();
            } else
                val = search.getValue();*/
            search(search.getValue());
        }
    }

    private void search(String val) {
        if (Strings.isBlank(val)) {
            for (Listgroup group : tables.getGroups()) {
                List<EntityVo> cv = data.get(group.getValue());
                if (cv != null) {
                    tables.getItems().removeAll(group.getItems());
                    createTables(group, cv);
                }
            }
        } else {
            for (Listgroup group : tables.getGroups()) {
                List<EntityVo> cv = data.get(group.getValue());
                if (cv != null) {
                    tables.getItems().removeAll(group.getItems());
                    List<EntityVo> cp = new ArrayList<EntityVo>();
                    for (EntityVo tv : cv) {
                        if (StringUtils.indexOfIgnoreCase(tv.getId(), val) >= 0
                                || StringUtils.indexOfIgnoreCase(tv.getName(),
                                val) >= 0) {
                            cp.add(tv);
                        }
                    }
                    createTables(group, cp);
                }
            }
        }
    }

    private void deleteTable(final EditorPanel editor) {
        if (editor.grid.getSelectedCount() > 0) {
            WebUtils.showConfirm(Labels.getLabel("button.delete"),
                    new EventListener<Event>() {
                        @Override
                        public void onEvent(Event event) throws Exception {
                            if (event.getName().equals(Events.ON_OK)) {
                                editor.onDelete();
                            }
                        }
                    });
        }
    }

    private void createEditorTab(EntityVo vo) {
        List<Tab> tabs = container.getTabs().getChildren();
        for (Tab tab : tabs) {
            Object val = tab.getValue();
            if (val instanceof EditorPanel) {
                if (vo.getId().equals(((EditorPanel) val).tb.getId())) {
                    tab.setSelected(true);
                    return;
                }
            }
        }
        Tab tab = new Tab(vo.getId());
        tab.setClosable(true);
        Tabpanel tpanel = new Tabpanel();
        tab.setValue(new EditorPanel().build(tpanel,
                (TableBean) StudioApp.execute(new GetEntityCmd(vo.getId()))));
        tab.setSelected(true);
        tab.addEventListener(Events.ON_CLOSE, this);
        tab.setParent(container.getTabs());
        tpanel.setParent(container.getTabpanels());
        setToolbarState(1);
    }

    private void setToolbarState(int state) {
        if (loginUserVo.isAuthorized("dataAdd"))
            insertBtn.setDisabled(state > 2);
        else
            insertBtn.setDisabled(true);
        if (loginUserVo.isAuthorized("dataDelete"))
            deleteBtn.setDisabled(state > 1);
        else
            deleteBtn.setDisabled(true);
        if (loginUserVo.isAuthorized("dataEdit")) {
            saveBtn.setDisabled(state != 2);
            undoBtn.setDisabled(state != 2);
        } else {
            saveBtn.setDisabled(true);
            undoBtn.setDisabled(true);
        }
        if (loginUserVo.isAuthorized("createSql"))
            runBtn.setDisabled(state != 3);
        else
            runBtn.setDisabled(true);
    }

    private void createQueryTab() {
        Tab tab = new Tab("SQL");
        tab.setClosable(true);
        Tabpanel tpanel = new Tabpanel();
        tab.setValue(new QueryPanel().build(tpanel));
        tab.setSelected(true);
        tab.addEventListener(Events.ON_CLOSE, this);
        tab.setParent(container.getTabs());
        tpanel.setParent(container.getTabpanels());
        setToolbarState(3);
    }

    private class EditorPanel implements EventListener<Event> {

        private Listbox grid;

        private Paging paging;

        private String sql;

        private TableBean tb;

        private List<Object[]> data;

        private int[] keyIndex;

        private int state;

        private String orderBy;

        private Map<String, FieldVo> filterParams;

        public TableBean getTableBean() {
            return tb;
        }

        public List<Object[]> getData() {
            return data;
        }

        EditorPanel build(Component parent, TableBean tb) {
            this.tb = tb;
            keyIndex = null;
            int fs = tb.getFields().size();
            if (tb.getKey() != null && !tb.getKey().isEmpty()) {
                keyIndex = new int[tb.getKey().size()];
                for (int i = 0; i < keyIndex.length; i++) {
                    for (int j = 0; j < fs; j++) {
                        if (tb.getFields().get(j).getName()
                                .equals(tb.getKey().get(i))) {
                            keyIndex[i] = j;
                            break;
                        }
                    }
                }
            }
            filterParams = new HashMap<String, FieldVo>();
            paging = new Paging();
            paging.setPageSize(15);
            grid = new Listbox();
            redrawGrid();

            Vlayout layout = new Vlayout();
            layout.setSpacing("0");
            layout.setHflex("1");
            layout.setVflex("1");

            grid.setHflex("1");
            grid.setVflex("1");
            grid.setSizedByContent(true);
            grid.setSpan(true);
            grid.appendChild(new Listhead());
            grid.getListhead().setSizable(true);
            if (loginUserVo.isAuthorized("dataAdd"))
                grid.setMultiple(true);
            grid.setCheckmark(true);
            String pid = RandomStringUtils.randomAlphanumeric(10);
            grid.getListhead().setMenupopup(pid);
            grid.setParent(layout);

            paging.setHflex("1");
            paging.setDetailed(true);
            paging.addEventListener(ZulEvents.ON_PAGING, this);
            paging.setParent(layout);

            Menupopup pop = new Menupopup();
            pop.setMold("bs");
            Menuitem filter = new Menuitem(Labels.getLabel("editor.db.filter"));
            filter.addEventListener(Events.ON_CLICK, this);
            //filter.setImage("~./images/filter.gif");
            filter.setParent(pop);
            pop.setId(pid);
            pop.setParent(layout);
            pop.addEventListener(Events.ON_OPEN, this);
            layout.setParent(parent);

            createHeader(this.tb.getFields());
            return this;
        }

        private void redrawGrid() {
            StringBuilder sb = new StringBuilder("SELECT ");
            Iterator<TableField> it = tb.getFields().iterator();
            while (it.hasNext()) {
                TableField tf = it.next();
                sb.append(tf.getName());
                if (it.hasNext())
                    sb.append(",");
            }
            sb.append(" FROM ").append(tb.getId());
            sql = sb.toString();
            if (tb.getKey() != null && !tb.getKey().isEmpty())
                orderBy = tb.getKey().get(0);
            else
                orderBy = tb.getFields().get(0).getName();
            BizQueryVo vo = new BizQueryVo();
            vo.setId(tb.getSubType());
            if (filterParams.isEmpty())
                vo.setSql(sql);
            else {
                sb.append(" WHERE ");
                Iterator<Map.Entry<String, FieldVo>> itr = filterParams
                        .entrySet().iterator();
                while (itr.hasNext()) {
                    Map.Entry<String, FieldVo> entry = itr.next();
                    sb.append(entry.getKey()).append(" ")
                            .append(entry.getValue().getName()).append("?");
                    if (itr.hasNext())
                        sb.append(" AND ");
                }
                vo.setSql(sb.toString());
                vo.setParams(Lang.collection2array(filterParams.values()));
            }
            vo.setOrderBy(orderBy);
            BizQueryResultVo result = StudioApp.execute(new QueryCmd(vo, 15));
            paging.setTotalSize(result.getTotalSize());
            redrawGridData(result.getResult().getData());
        }

        private void createHeader(List<TableField> columns) {
            grid.getListhead().getChildren().clear();
            Comparator<Listitem> comparator = new Comparator<Listitem>() {
                public int compare(Listitem o1, Listitem o2) {
                    return 0;
                }
            };
            for (int i = 0; i < columns.size(); i++) {
                TableField tf = columns.get(i);
                Listheader header = new Listheader(Strings.isBlank(tf.getDescription()) ? tf.getName(): tf.getDescription());
                if (keyIndex != null) {
                    for (int idx : keyIndex) {
                        if (idx == i) {
                            header.setIconSclass("z-icon-key");
                            break;
                        }
                    }
                }
                header.setValue(tf);
                header.setSortAscending(comparator);
                header.setSortDescending(comparator);
                header.addEventListener(Events.ON_SORT, this);
                header.setTooltiptext(tf.getName());
                grid.getListhead().appendChild(header);
            }
        }

        private void onSave() {
            StringBuilder sb = new StringBuilder();
            List<FieldVo> params = new ArrayList<FieldVo>();
            int createCount = 0;
            for (Listitem li : grid.getItems()) {
                String code = (String) li.getAttribute("code");
                if (code.equals("C")) {
                    sb.setLength(0);
                    params.clear();
                    Object[] data = li.getValue();
                    int size = data.length;
                    if (size > tb.getFields().size())
                        size = tb.getFields().size();
                    sb.append("INSERT INTO ").append(tb.getId()).append("(");
                    for (int i = 0; i < size; i++) {
                        TableField tf = tb.getFields().get(i);
                        sb.append(tf.getName());
                        if (i < size - 1)
                            sb.append(",");
                        params.add(new FieldVo(tf.getType(), data[i]));
                    }
                    sb.append(") VALUES(")
                            .append(StringUtils.repeat("?", ",", tb.getFields()
                                    .size())).append(")");
                    createCount++;
                    StudioApp.execute(new UpdateCmd(tb.getSubType(), sb
                            .toString(), params));
                    li.setAttribute("code", "R");
                } else if (code.equals("U")) {
                    sb.setLength(0);
                    params.clear();
                    Object[] data = li.getValue();
                    sb.append("UPDATE ").append(tb.getId()).append(" SET ");
                    int size = data.length;
                    if (size > tb.getFields().size())
                        size = tb.getFields().size();
                    for (int i = 0; i < size; i++) {
                        TableField tf = tb.getFields().get(i);
                        sb.append(tf.getName()).append("=?");
                        if (i < size - 1)
                            sb.append(",");
                        params.add(new FieldVo(tf.getType(), data[i]));
                    }
                    sb.append(" WHERE ");
                    for (int i = 0; i < keyIndex.length; i++) {
                        TableField tf = tb.getFields().get(keyIndex[i]);
                        sb.append(tf.getName()).append("=?");
                        if (i < keyIndex.length - 1)
                            sb.append(" AND ");
                        params.add(new FieldVo(tf.getType(), data[keyIndex[i]]));
                    }
                    StudioApp.execute(new UpdateCmd(tb.getSubType(), sb
                            .toString(), params));
                    li.setAttribute("code", "R");
                }
            }
            paging.setTotalSize(paging.getTotalSize() + createCount);
            onRefresh();
        }

        private void onDelete() {
            StringBuilder sb = new StringBuilder("DELETE FROM " + tb.getId())
                    .append(" WHERE ");
            int fs = tb.getFields().size();
            if (keyIndex != null) {
                for (int i = 0; i < keyIndex.length; i++) {
                    sb.append(tb.getKey().get(i)).append("=?");
                    if (i < keyIndex.length - 1)
                        sb.append(" AND ");
                }
            } else {
                for (int j = 0; j < fs; j++) {
                    sb.append(tb.getFields().get(j).getName()).append("=?");
                    if (j < fs - 1)
                        sb.append(" AND ");
                }
            }
            List<List<FieldVo>> params = new ArrayList<List<FieldVo>>();
            for (Listitem li : grid.getSelectedItems()) {
                Object[] data = li.getValue();
                List<FieldVo> param = new ArrayList<FieldVo>();
                if (keyIndex == null) {
                    for (int i = 0; i < data.length; i++)
                        param.add(new FieldVo(tb.getFields().get(i).getType(),
                                data[i]));
                } else {
                    for (int i : keyIndex)
                        param.add(new FieldVo(tb.getFields().get(i).getType(),
                                data[i]));
                }
                params.add(param);
            }
            StudioApp.execute(new BatchUpdateCmd(tb.getSubType(),
                    sb.toString(), params));
            paging.setTotalSize(paging.getTotalSize() - grid.getSelectedCount());
            onRefresh();
        }

        private void onCreate() {
            Object[] vo = new Object[tb.getFields().size()];
            for (int i = 0; i < vo.length; i++) {
                FieldType type = tb.getFields().get(i).getType();
                switch (type) {
                    case INT:
                        vo[i] = 0;
                        break;
                    case LONG:
                        vo[i] = 0L;
                        break;
                    case NUMERIC:
                        vo[i] = 0d;
                        break;
                    case VARCHAR:
                    case CLOB:
                        vo[i] = "";
                        break;
                    case CHAR:
                        vo[i] = ' ';
                        break;
                    case BOOLEAN:
                        vo[i] = false;
                        break;
                    default:
                        vo[i] = null;
                }
            }
            createItem(true, vo);
            setToolbarState(2);
            state = 2;
        }

        private void onRefresh() {
            Events.sendEvent(paging, new PagingEvent(ZulEvents.ON_PAGING,
                    paging, paging.getActivePage()));
        }

        private void redrawGridData(List<Object[]> data) {
            this.data = data;
            grid.getItems().clear();
            for (Object[] vo : data)
                createItem(false, vo);
            setToolbarState(1);
            state = 1;
        }

        private void createItem(boolean isCreate, Object[] vo) {
            Listitem row = new Listitem();
            row.setValue(vo);
            int size = vo.length;
            if (tb.getFields().size() < size)
                size = tb.getFields().size();
            if (isCreate || keyIndex != null) {// 如果没有主键就不能更新
                TableField current = null;
                try {
                    boolean editable = loginUserVo.isAuthorized("dataEdit");
                    for (int i = 0; i < size; i++) {
                        current = tb.getFields().get(i);
                        if (!isCreate && keyIndex != null) {// 属于主键的栏位不能编辑
                            boolean find = false;
                            for (int idx : keyIndex) {
                                if (idx == i) {
                                    Listcell c = new Listcell(
                                            vo[i] == null ? ""
                                                    : vo[i].toString());
                                    row.appendChild(c);
                                    find = true;
                                    break;
                                }
                            }
                            if (find)
                                continue;
                        }
                        switch (current.getType()) {
                            case CHAR:
                            case VARCHAR:
                            case CLOB:
                                Listcell c = new Listcell();
                                if (editable) {
                                    Textbox tx = new Textbox(vo[i] == null ? ""
                                            : vo[i].toString());
                                    tx.setInplace(true);
                                    tx.setHflex("1");
                                    tx.addEventListener(Events.ON_CHANGE, this);
                                    c.appendChild(tx);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            case BOOLEAN:
                                c = new Listcell();
                                if (editable) {
                                    Checkbox cbx = new Checkbox();
                                    if (vo[i] != null
                                            && (vo[i].equals("1") || vo[i]
                                            .equals(Boolean.TRUE)))
                                        cbx.setChecked(true);
                                    cbx.addEventListener(Events.ON_CHECK, this);
                                    c.appendChild(cbx);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            case DATETIME:
                            case DATE:
                                c = new Listcell();
                                if (editable) {
                                    Datebox db = new Datebox();
                                    if (vo[i] instanceof Date)
                                        db.setValue((Date) vo[i]);
                                    db.setHflex("1");
                                    db.setInplace(true);
                                    db.addEventListener(Events.ON_CHANGE, this);
                                    c.appendChild(db);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            case TIME:
                                c = new Listcell();
                                if (editable) {
                                    Timebox mx = new Timebox((Date) vo[i]);
                                    mx.setHflex("1");
                                    mx.setInplace(true);
                                    mx.addEventListener(Events.ON_CHANGE, this);
                                    c.appendChild(mx);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            case INT:
                                c = new Listcell();
                                if (editable) {
                                    Intbox ix = new Intbox();
                                    if (vo[i] != null && vo[i] instanceof Number)
                                        ix.setValue(((Number) vo[i]).intValue());
                                    ix.setHflex("1");
                                    ix.setInplace(true);
                                    ix.addEventListener(Events.ON_CHANGE, this);
                                    c.appendChild(ix);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            case LONG:
                                c = new Listcell();
                                if (editable) {
                                    Longbox lx = new Longbox();
                                    if (vo[i] != null && vo[i] instanceof Number)
                                        lx.setValue(((Number) vo[i]).longValue());
                                    lx.setHflex("1");
                                    lx.setInplace(true);
                                    lx.addEventListener(Events.ON_CHANGE, this);
                                    c.appendChild(lx);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            case NUMERIC:
                                c = new Listcell();
                                if (editable) {
                                    Doublebox dx = new Doublebox();
                                    if (vo[i] != null && vo[i] instanceof Number)
                                        dx.setValue(((Number) vo[i]).doubleValue());
                                    dx.setHflex("1");
                                    dx.setInplace(true);
                                    dx.addEventListener(Events.ON_CHANGE, this);
                                    c.appendChild(dx);
                                } else
                                    c.setLabel(vo[i] == null ? "" : vo[i].toString());
                                row.appendChild(c);
                                break;
                            default:
                                row.appendChild(new Listcell(vo[i] == null ? ""
                                        : vo[i].toString()));
                        }
                    }
                    row.setParent(grid);
                    row.setAttribute("code", isCreate ? "C" : "R");
                } catch (ClassCastException ex) {
                    throw new ClassCastException(current.getName() + "->"
                            + ex.getMessage());
                }
            } else {
                for (int i = 0; i < size; i++)
                    row.appendChild(new Listcell(vo[i] == null ? "" : vo[i]
                            .toString()));
                row.setParent(grid);
                row.setAttribute("code", "R");
            }
        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (event.getTarget() instanceof Bandbox) {// 过滤器
                TableField tf = (TableField) event.getTarget().getAttribute(
                        "ref");
                Bandbox bb = (Bandbox) event.getTarget();
                String value = null;
                if (event instanceof OpenEvent) {
                    OpenEvent evt = (OpenEvent) event;
                    value = (String) evt.getValue();
                } else
                    value = bb.getValue();
                if (!Strings.isBlank(value)) {
                    Object val = FieldType.cast(value, tf.getType());
                    String op = ((Listbox) bb.getPreviousSibling())
                            .getSelectedItem().getLabel();
                    filterParams.put(tf.getName(), new FieldVo(op,
                            tf.getType(), val));
                } else
                    filterParams.remove(tf.getName());
                redrawGrid();
                event.getTarget().getRoot().detach();
            } else if (event.getName().equals(ZulEvents.ON_PAGING)) {
                PagingEvent pe = (PagingEvent) event;
                int pageNo = pe.getActivePage() + 1;
                BizQueryVo vo = new BizQueryVo();
                vo.setId(tb.getSubType());
                if (filterParams.isEmpty())
                    vo.setSql(sql);
                else {
                    StringBuilder sb = new StringBuilder(sql).append(" WHERE ");
                    Iterator<Map.Entry<String, FieldVo>> itr = filterParams
                            .entrySet().iterator();
                    while (itr.hasNext()) {
                        Map.Entry<String, FieldVo> entry = itr.next();
                        sb.append(entry.getKey()).append(" ")
                                .append(entry.getValue().getName()).append("?");
                        if (itr.hasNext())
                            sb.append(" AND ");
                    }
                    vo.setSql(sb.toString());
                    vo.setParams(Lang.collection2array(filterParams.values()));
                }
                vo.setOrderBy(orderBy);
                List<Object[]> data = StudioApp.execute(paging, new PagingCmd(
                        vo, paging.getPageSize(), pageNo));
                redrawGridData(data);
            } else if (event.getName().equals(Events.ON_CHANGE)
                    || event.getName().equals(Events.ON_CHECK)) {
                Listitem li = (Listitem) event.getTarget().getParent()
                        .getParent();
                Object[] data = li.getValue();
                int index = li.getChildren().indexOf(
                        event.getTarget().getParent());
                if (event.getTarget() instanceof InputElement)
                    data[index] = ((InputElement) event.getTarget())
                            .getRawValue();
                else
                    data[index] = ((Checkbox) event.getTarget()).isChecked();
                if (!li.getAttribute("code").equals("C"))
                    li.setAttribute("code", "U");
                setToolbarState(2);
                state = 2;
            } else if (event.getName().equals(Events.ON_OPEN)) {
                OpenEvent oe = (OpenEvent) event;
                if (oe.isOpen()) {
                    TableField tf = ((Listheader) oe.getReference()).getValue();
                    oe.getTarget().setAttribute("ref", tf);
                }
            } else if (event.getName().equals(Events.ON_SORT)) {
                SortEvent evt = (SortEvent) event;
                TableField tf = ((Listheader) evt.getTarget()).getValue();
                if (evt.isAscending())
                    orderBy = tf.getName();
                else
                    orderBy = tf.getName() + " DESC";
                paging.setActivePage(0);
                onRefresh();
            } else if (event.getTarget() instanceof Menuitem) {
                TableField tf = (TableField) event.getTarget().getParent()
                        .getAttribute("ref");
                FieldVo fv = filterParams.get(tf.getName());
                String title = tf.getDescription() == null ? tf.getName(): tf.getDescription();
                Window win = new Window(Labels.getLabel("editor.db.filter")
                        + ":" + title, "none", true);
                Listbox cbx = new Listbox();
                cbx.setMold("select");
                cbx.setHeight("23px");
                List<String> strings;
                if (tf.getType() == FieldType.VARCHAR
                        || tf.getType() == FieldType.CHAR
                        || tf.getType() == FieldType.CLOB)
                    strings = Arrays.asList(new String[]{"like", "=", "<>", ">", "<", ">=", "<="});
                else
                    strings = Arrays.asList(new String[]{"=", "<>", ">", "<", ">=", "<="});
                for (String name : strings) {
                    Listitem listitem = new Listitem(name);
                    cbx.appendChild(listitem);
                }
                if (fv == null)
                    cbx.setSelectedIndex(0);
                else {
                    for (int i = 0; i < strings.size(); i++) {
                        if (strings.get(i).equals(fv.getName())) {
                            cbx.setSelectedIndex(i);
                            break;
                        }
                    }
                }
                /*if (tf.getType() == FieldType.VARCHAR
                        || tf.getType() == FieldType.CHAR
                        || tf.getType() == FieldType.CLOB)
                    cbx.setModel(new SimpleListModel<String>(new String[]{
                            "like", "=", "<>", ">", "<", ">=", "<="}));
                else {
                    cbx.setModel(new SimpleListModel<String>(Arrays
                            .asList(new String[]{"=", "<>", ">", "<", ">=",
                                    "<="})));
                }
                if (fv == null)
                    cbx.setSelectedIndex(0);
                else {
                    int size = cbx.getModel().getSize();
                    for (int i = 0; i < size; i++) {
                        if (cbx.getModel().getElementAt(i).equals(fv.getName())) {
                            cbx.setSelectedIndex(i);
                            break;
                        }
                    }
                }*/
                cbx.setWidth("60px");
                cbx.setParent(win);
                Bandbox bx = new Bandbox();
                bx.setSclass("epstudio-left");
                bx.setHflex("1");
                bx.addEventListener(Events.ON_OK, this);
                bx.addEventListener(Events.ON_OPEN, this);
                bx.setPlaceholder(Labels.getLabel("editor.db.filter.content"));
                bx.setAttribute("ref", tf);
                if (fv != null)
                    bx.setValue(fv.getValue().toString());
                bx.setParent(win);
                win.setPage(event.getPage());
                win.setHeight("70px");
                win.setWidth("310px");
                win.setPosition("center");
                win.doHighlighted();
            }
        }

    }

    private class QueryPanel implements EventListener<Event> {

        private CMeditor editor;

        private Listbox grid;

        private Paging paging;

        private String sql;

        private TableBean tb;

        private BizQueryResultVo result;

        QueryPanel build(Component parent) {
            Borderlayout layout = new Borderlayout();
            North north = new North();
            north.setSplittable(true);
            north.setSize("200px");
            editor = new CMeditor();
            editor.setTheme(Contexts.getUser().getEditorTheme());
            editor.setMode("text/x-sql");
            editor.setHflex("1");
            editor.setVflex("1");
            editor.setBorder("none");
            editor.setParent(north);
            north.setParent(layout);
            Center center = new Center();
            center.setBorder("none");
            center.setHflex("1");
            center.setVflex("1");
            Vlayout vlayout = new Vlayout();
            vlayout.setVflex("1");
            vlayout.setHflex("1");
            vlayout.setParent(center);
            grid = new Listbox();
            grid.setHflex("1");
            grid.setVflex("1");
            grid.setSizedByContent(true);
            grid.setSpan(true);
            grid.setMultiple(true);
            grid.setCheckmark(true);
            //grid.appendChild(new Rows());
            //grid.appendChild(new Columns());
            grid.addEventListener("onRefresh", this);
            grid.appendChild(new Listhead());
            grid.getListhead().setSizable(true);
            grid.setParent(vlayout);
            Hlayout hlayout = new Hlayout();
            hlayout.setHflex("1");
            hlayout.setParent(vlayout);
            Div div = new Div();
            div.setHflex("1");
            div.setParent(hlayout);
            Button screenExport = new Button(Labels.getLabel("editor.db.screenExport"));
            //screenExport.setSclass("pull-right epstudio-top");
            screenExport.setImage("~./images/db_export.gif");
            //screenExport.setId("screenExport");
            screenExport.addEventListener(Events.ON_CLICK, this);
            screenExport.setParent(hlayout);
            center.setParent(layout);
            South south = new South();
            south.setBorder("none");
            south.setSize("30px");
            south.setHflex("1");
            paging = new Paging();
            paging.setPageSize(20);
            paging.setHflex("1");
            paging.setParent(south);
            paging.setDetailed(true);
            paging.addEventListener(ZulEvents.ON_PAGING, this);
            south.setParent(layout);
            layout.setParent(parent);
            layout.setDroppable("table");
            layout.addEventListener(Events.ON_DROP, this);
            return this;
        }

        void smartSql(EntityVo vo) {
            tb = (TableBean) StudioApp.execute(new GetEntityCmd(vo.getId()));
            StringBuilder sb = new StringBuilder("SELECT ");
            for (TableField tf : tb.getFields())
                sb.append(tf.getName()).append(",");
            sb.deleteCharAt(sb.length() - 1);
            sb.append(" FROM ").append(tb.getId()).append(" WHERE 1=1");
            editor.setValue(sb.toString());
        }

        void run() {
            if (editor.getValue() == null
                    || editor.getValue().toString().trim().equals(""))
                return;
            BizQueryVo vo = new BizQueryVo();
            vo.setId(tb == null ? null : tb.getSubType());
            sql = editor.getValue().toString();
            if (sql.toUpperCase().startsWith("SELECT")) {
                vo.setSql(sql);
                result = StudioApp.execute(new QueryCmd(vo,
                        paging.getPageSize()));
                paging.setActivePage(0);
                paging.setTotalSize(result.getTotalSize());
                createHeader(result.getResult().getColumns());
                redraw(result.getResult().getData());
                Events.echoEvent("onRefresh", grid, null);
            }
        }

        private void createHeader(List<String> columns) {
            grid.getListhead().getChildren().clear();
            for (String name : columns)
                grid.getListhead().appendChild(new Listheader(name));
        }

        private void redraw(List<Object[]> data) {
            grid.getItems().clear();
            for (Object[] vo : data) {
                Listitem row = new Listitem();
                for (Object v : vo)
                    row.appendChild(new Listcell(v == null ? "" : v.toString()));
                row.setParent(grid);
                row.setValue(vo);
            }
        }

        @Override
        public void onEvent(Event event) throws Exception {
            if (event.getName().equals(Events.ON_CLICK)) {
                if (result == null) {
                    return;
                }
                ResultVo resultVo = result.getResult();
                if (resultVo.getTableNames() == null || resultVo.getTableNames().size() == 0) {
                    return;
                }
                boolean flag = false;
                String var = resultVo.getTableNames().get(0);
                for (String tableName : resultVo.getTableNames()) {
                    if (!tableName.equals(var)){
                        flag = true;
                    }
                }
                if (flag){
                    WebUtils.showError(Labels.getLabel("editor.db.onlyOneExport"));
                    return;
                }
                if (grid.getSelectedCount() > 0) {
                    List<List<String>> columnsList = new ArrayList<>();
                    List<List<Object[]>> datas = new ArrayList<>();
                    List<Object[]> dataList = new ArrayList<>();
                    columnsList.add(resultVo.getColumns());
                    for (Listitem li : grid.getSelectedItems()) {
                        Object[] data = li.getValue();
                        dataList.add(data);
                    }
                    datas.add(dataList);
                    HSSFWorkbook wb = new HSSFWorkbook();
                    for (int r = 0; r < columnsList.size(); r++) {
                        List<String> columns = columnsList.get(r);

                        String[] sheetOneTitle = new String[columns.size()];
                        for (int i = 0; i < columns.size(); i++) {
                            sheetOneTitle[i] = columns.get(i);
                        }
                        List<Object[]> data = datas.get(r);
                        String sheetOnecontent[][] = null;
                        if (data != null && data.size() != 0) {
                            sheetOnecontent = new String[data.size()][data.get(0).length];
                            for (int i = 0; i < data.size(); i++) {
                                Object[] objects = data.get(i);
                                for (int a = 0; a < objects.length; a++) {
                                    sheetOnecontent[i][a] = objects[a] != null ? objects[a] + "" : "";
                                }
                            }
                        }
                        List<Map<String, Object>> excelData = new ArrayList<>();
                        Map<String, Object> three = new HashMap<String, Object>();
                        three.put("title", sheetOneTitle);
                        three.put("values", sheetOnecontent);
                        excelData.add(three);
                        ExportExcel.getHSSFWorkbook(resultVo.getTableNames().get(0), excelData, wb);
                    }
                    try {
                        File tempFile = File.createTempFile("datas", ".xls");
                        FileOutputStream os = new FileOutputStream(tempFile);
                        wb.write(os);
                        os.flush();
                        os.close();
                        Filedownload.save(tempFile, "application/vnd.ms-excel");
                        tempFile.deleteOnExit();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return;
            }
            if (event.getName().equals("onRefresh")) {
                paging.setActivePage(0);
                paging.setTotalSize(result.getTotalSize());
                createHeader(result.getResult().getColumns());
                redraw(result.getResult().getData());
                return;
            }
            if (event.getName().equals(ZulEvents.ON_PAGING)) {
                PagingEvent pe = (PagingEvent) event;
                int pageNo = pe.getActivePage() + 1;
                BizQueryVo vo = new BizQueryVo();
                if (tables.getSelectedItem() != null) {
                    EntityVo tv = tables.getSelectedItem().getValue();
                    vo.setId(tv.getSubType());
                }
                vo.setSql(sql);
                List<Object[]> data = StudioApp.execute(paging, new PagingCmd(
                        vo, paging.getPageSize(), pageNo));
                redraw(data);
            } else if (event.getName().equals(Events.ON_DROP)) {
                DropEvent de = (DropEvent) event;
                EntityVo vo = ((Listitem) de.getDragged()).getValue();
                smartSql(vo);
            }
        }

    }

    /*private boolean validate(TableBean entity) {
        if (StudioApp.execute(new CheckCmd(entity.getId()))) {
            WebUtils.showError(Labels.getLabel("entity.exists.id",
                    new String[]{entity.getId()}));
            return false;
        }
        if (Strings.isBlank(entity.getName())) {
            WebUtils.notEmpty(Labels.getLabel("entity.name"));
            return false;
        }
        if (entity.getKey() == null || entity.getKey().isEmpty()) {
            WebUtils.showError(Labels.getLabel("entity.table.key.set"));
            return false;
        }
        if (entity.getFields() == null || entity.getFields().isEmpty()) {
            WebUtils.showError(Labels.getLabel("entity.table.field.set"));
            return false;
        }
        if (entity.isAutoKey()) {
            if (entity.getKey().size() == 1) {
                String key = entity.getKey().get(0);
                for (TableField field : entity.getFields()) {
                    if (field.getName().equals(key)) {
                        if (field.getType() != FieldType.INT
                                && field.getType() != FieldType.LONG
                                && field.getType() != FieldType.NUMERIC) {
                            WebUtils.showError(Labels
                                    .getLabel("entity.table.auto.key.error"));
                            return false;
                        }
                        break;
                    }
                }
            } else {
                WebUtils.showError(Labels
                        .getLabel("entity.table.auto.key.error"));
                return false;
            }
        }
        for (TableField field : entity.getFields()) {
            if (Strings.isBlank(field.getName())) {
                WebUtils.showError(Labels
                        .getLabel("entity.table.field.name.not.empty"));
                return false;
            }
        }
        if (entity.getIndexes() != null) {
            if (entity.getIndexes().isEmpty()) {
                entity.setIndexes(null);
            } else {
                for (TableIndex index : entity.getIndexes()) {
                    if (Strings.isBlank(index.getName())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.table.index.name"));
                        return false;
                    }
                    if (Strings.isBlank(index.getFields())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.table.index.field"));
                        return false;
                    }
                }
            }
        }
        if (entity.getForeignKeys() != null) {
            if (entity.getForeignKeys().isEmpty()) {
                entity.setForeignKeys(null);
            } else {
                for (TableFk fk : entity.getForeignKeys()) {
                    if (Strings.isBlank(fk.getName())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.table.fk.name"));
                        return false;
                    }
                    if (Strings.isBlank(fk.getSourceFields())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.table.fk.field"));
                        return false;
                    }
                    if (Strings.isBlank(fk.getReferences())) {
                        WebUtils.notEmpty(Labels
                                .getLabel("entity.table.fk.table"));
                        return false;
                    }
                    if (Strings.isBlank(fk.getToFields())) {
                        WebUtils.notEmpty(Labels.getLabel("entity.table.fk.to"));
                        return false;
                    }
                    if (StringUtils.countMatches(fk.getSourceFields(), ",") != StringUtils
                            .countMatches(fk.getToFields(), ",")) {// 栏位数不匹配
                        WebUtils.showError(Labels
                                .getLabel("entity.table.fk.field.match"));
                        return false;
                    }
                }
            }
        }
        return true;
    }*/

}
